package com.huatai.datacenter.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.huatai.datacenter.entity.ClusterEntity;
import com.huatai.datacenter.entity.DataSourceEntity;
import com.huatai.datacenter.entity.Index.IndexRateVO;
import com.huatai.datacenter.entity.Index.IndexUseageVO;
import com.huatai.datacenter.entity.Index.IndexValuesVO;
import com.huatai.datacenter.entity.RequestLogEntity;
import com.huatai.datacenter.entity.TopicTaskEntity;
import com.huatai.datacenter.entity.datadesensitization.DesensitizationApplyEntity;
import com.huatai.datacenter.entity.datadesensitization.DesensitizationRuleEntity;
import com.huatai.datacenter.entity.datamodel.DataModelApplyEntity;
import com.huatai.datacenter.entity.datamodel.DataModelBaseEntity;
import com.huatai.datacenter.entity.datamodel.DataModelEntity;
import com.huatai.datacenter.entity.datamodel.DataModelTypeEntity;
import com.huatai.datacenter.entity.dataquality.QualityBaseEntity;
import com.huatai.datacenter.entity.dataquality.QualityLogEntity;
import com.huatai.datacenter.entity.dataquality.QualityRuleEntity;
import com.huatai.datacenter.mapper.IndexMapper;
import com.huatai.datacenter.service.*;
import com.huatai.datacenter.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author gusiyi
 * @version 1.0
 * @className IndexServiceImpl
 * @description 描述：
 * @date 2023/7/18 14:20
 */
@Service
public class IndexServiceImpl implements IndexService {

	@Autowired
	private DataModelTypeService dataModelTypeService;

	@Autowired
	private DataModelService dataModelService;

	@Autowired
	private DataModelApplyService dataModelApplyService;

	@Autowired
	private QualityRuleService qualityRuleService;

	@Autowired
	private QualityLogService qualityLogService;

	@Autowired
	private DesensitizationRuleService desensitizationRuleService;

	@Autowired
	private DesensitizationApplyService desensitizationApplyService;

	@Autowired
	private DataSourceService dataSourceService;

	@Autowired
	private TopicTaskService topicTaskService;

	@Autowired
	private ApiService apiService;

	@Autowired
	private ServerObjectService serverObjectService;

	@Autowired
	private IndexMapper indexMapper;

	@Autowired
	private RequestService requestService;



	@Override
	public List<IndexUseageVO> getUseageInfo() {
		List<IndexUseageVO> resultList = new ArrayList<>(4);
		resultList.add(getDataModelUseage());
		resultList.add(getModelApplyUseage());
		resultList.add(getDataQualityUseage());
		resultList.add(getDesensitizationUseage());
		return resultList;
	}

	@Override
	public IndexRateVO getRateData(String type) {
		IndexRateVO indexRateVO = new IndexRateVO();
		if("dataSource".equals(type)){
			List<IndexValuesVO> dataSourceRate = indexMapper.getDataSourceRate();
			indexRateVO.setTitle("数据源占比");
			indexRateVO.setValues(dataSourceRate);
		}else if("cluster".equals(type)){
			List<IndexValuesVO> clusterRate = indexMapper.getClusterRate();
			indexRateVO.setTitle("集群占主题任务比数");
			indexRateVO.setValues(clusterRate);
		}else if ("dataModel".equals(type)){
			List<IndexValuesVO> modelRate = indexMapper.getModelRate();
			indexRateVO.setTitle("模型占主题任务比数");
			indexRateVO.setValues(modelRate);
		}
		return indexRateVO;
	}

	@Override
	public List<IndexValuesVO> getServiceInfo() {
		List<IndexValuesVO> resultList = new ArrayList<>(5);
		//实时服务数
		long topicTaskInfoCount = topicTaskService.count();
		resultList.add(new IndexValuesVO("实时服务数",String.valueOf(topicTaskInfoCount)));
		//服务接口数
		long apiCount = apiService.count();
		resultList.add(new IndexValuesVO("服务接口数",String.valueOf(apiCount)));
		//todo 服务次数
		long serverCount = requestService.count();
		resultList.add(new IndexValuesVO("服务次数",String.valueOf(serverCount)));
		//服务对象数量
		long serverObjectCount = serverObjectService.count();
		resultList.add(new IndexValuesVO("服务对象数",String.valueOf(serverObjectCount)));
		//todo 服务间隔
		String value = calculateDuration();
		resultList.add(new IndexValuesVO("服务间隔",value));
		return resultList;
	}

	public String calculateDuration(){

		List<RequestLogEntity> list = null;

		String key = RedisUtil.buildDbTableKey(RequestLogEntity.class);

		list = (List<RequestLogEntity>) RedisUtil.get(key,null);
		if (list == null){
			list = requestService.list().stream().sorted(Comparator.comparing(RequestLogEntity::getCreateTime).reversed()).collect(Collectors.toList());
			RedisUtil.set(key, list);
		}else {
			list = list.stream().sorted(Comparator.comparing(RequestLogEntity::getCreateTime).reversed()).collect(Collectors.toList());
		}
		double resultData = 0;
		if (list != null){
			Timestamp now =  Timestamp.valueOf(LocalDateTime.now());
			Timestamp data = Timestamp.valueOf(list.get(0).getCreateTime());

			long sta = now.getTime() - data.getTime();
			resultData = sta / 3600000;
		}


		return String.valueOf(resultData);

	}

	private IndexUseageVO getDataModelUseage(){
		IndexUseageVO dataModelUseage = new IndexUseageVO();
		//获取数据模型类型数量
		LambdaQueryWrapper<DataModelTypeEntity> dataModelTypeQuery = Wrappers.lambdaQuery();
		dataModelTypeQuery
			.eq(DataModelBaseEntity::getDeleted,false);
		long dataModelTypeCount = dataModelTypeService.count(dataModelTypeQuery);
		//获取数据模型数量
		LambdaQueryWrapper<DataModelEntity> dataModelQuery = Wrappers.lambdaQuery();
		dataModelQuery
			.eq(DataModelBaseEntity::getDeleted,false);
		long dataModelCount = dataModelService.count(dataModelQuery);
		setUseageInfo(dataModelUseage,"数据模型统计","数据模型类型数量",dataModelTypeCount,"数据模型数量",dataModelCount);
		return dataModelUseage;
	}

	private IndexUseageVO getModelApplyUseage(){
		IndexUseageVO modelApplyUseage = new IndexUseageVO();
		//获取接入应用数量
		LambdaQueryWrapper<DataModelApplyEntity> dataModelApplyInPutQuery = Wrappers.lambdaQuery();
		dataModelApplyInPutQuery
			.eq(DataModelBaseEntity::getDeleted,false)
			.eq(DataModelApplyEntity::getApplyTypeNum,1);
		long inputCount = dataModelApplyService.count(dataModelApplyInPutQuery);
		//获取服务应用数量
		LambdaQueryWrapper<DataModelApplyEntity> dataModelApplyOutputQuery = Wrappers.lambdaQuery();
		dataModelApplyOutputQuery
			.eq(DataModelBaseEntity::getDeleted,false)
			.eq(DataModelApplyEntity::getApplyTypeNum,2);
		long outputCount = dataModelApplyService.count(dataModelApplyOutputQuery);
		setUseageInfo(modelApplyUseage,"模型应用统计","接入应用数量",inputCount,"服务应用数量",outputCount);
		return modelApplyUseage;
	}

	private IndexUseageVO getDataQualityUseage(){
		IndexUseageVO dataQualityUseage = new IndexUseageVO();
		//获取质量规则数量
		LambdaQueryWrapper<QualityRuleEntity> ruleQuery = Wrappers.lambdaQuery();
		ruleQuery
			.eq(QualityBaseEntity::getDeleted,false);
		long ruleCount = qualityRuleService.count(ruleQuery);
		//获取质量日志数量
		LambdaQueryWrapper<QualityLogEntity> logQuery = Wrappers.lambdaQuery();
		logQuery
			.eq(QualityBaseEntity::getDeleted,false);
		long logCount = qualityLogService.count(logQuery);
		setUseageInfo(dataQualityUseage,"数据质量统计","质量规则数量",ruleCount,"质量日志数量",logCount);
		return dataQualityUseage;
	}

	private IndexUseageVO getDesensitizationUseage(){
		IndexUseageVO desensitizationUseage = new IndexUseageVO();
		//获取脱敏规则数量
		LambdaQueryWrapper<DesensitizationRuleEntity> ruleQuery = Wrappers.lambdaQuery();
		ruleQuery
			.eq(DesensitizationRuleEntity::getDeleted,false);
		long ruleCount = desensitizationRuleService.count(ruleQuery);
		//获取脱敏应用数量
		LambdaQueryWrapper<DesensitizationApplyEntity> applyQuery = Wrappers.lambdaQuery();
		applyQuery
			.eq(DesensitizationApplyEntity::getDeleted,false);
		long applyCount = desensitizationApplyService.count(applyQuery);
		setUseageInfo(desensitizationUseage,"脱敏脱密统计","脱敏规则数量",ruleCount,"脱敏应用数量",applyCount);
		return desensitizationUseage;
	}

	private void setUseageInfo(IndexUseageVO useageVO, String title,String name1,long value1,String name2,long value2){
		useageVO.setTitle(title);
		List<IndexValuesVO> values = new ArrayList<>(2);
		values.add(new IndexValuesVO(name1,String.valueOf(value1)));
		values.add(new IndexValuesVO(name2,String.valueOf(value2)));
		useageVO.setValues(values);
	}
}
